<template>
<!-- https://blog.csdn.net/weixin_43752765/article/details/104845724 -->
<!-- https://www.jianshu.com/p/1c073a5bc584 -->
  <div class="container">
    <TopPart :isFunc="true" />
    <div style="text-align:center;margin-top:76px;">
      <!-- <van-button
        @click="initUserInfo"
        icon="replay"
      >
        刷新信息
      </van-button> -->
    </div>
    <van-divider
      :style="{ color: '#1989fa', borderColor: '#1989fa', padding: '0 16px'}"
    >
      头像
    </van-divider>
    <!-- 头像修改 -->
    <div class="avatar-wrapper">
      <input class="imageRead" ref="imageRead" @change="selectImage" accept="image/*" type="file" />
      <div class="photo-wrap mt20">
        <img @click="clickPhoto" class="photo" :src="userAvatar" alt />
      </div>
      <van-overlay z-index="2" style="background-color:rgba(0,0,0,.85)!important;" :show="showCrop">
        <div class="crop-wrapper" @click.stop>
          <div>
            <img id="cropImage" ref="cropImage" src alt />
          </div>
          <div class="crop-options">
            <van-button plain type="info" size="small" @click="cancelCrop">取消</van-button>
            <van-button plain type="info" size="small" @click="largerImg">放大</van-button>
            <van-button plain type="info" size="small" @click="smallerImg">缩小</van-button>
            <van-button plain type="info" size="small" @click="resetCrop">复位</van-button>
            <van-button plain type="info" size="small" @click="scaleCrop">反转</van-button>
            <van-button plain type="info" size="small" @click="rotateCrop">旋转</van-button>
            <van-button plain type="info" size="small" @click="submitCrop">确定</van-button>
          </div>
        </div>
      </van-overlay>
    </div>
    <van-divider
      :style="{ color: '#1989fa', borderColor: '#1989fa', padding: '0 16px' }"
    >
      背景图
    </van-divider>
    <!-- 主页背景图添加 -->
    <div class="bg">
      <van-uploader 
        preview-size="160px"
        v-model="background"
        :max-count="1"
        upload-text="大小限5MB"
        upload-icon="plus"
        :max-size="5*1024*1024"
        :before-read="beforeRead"
        :after-read="afterRead"
        @oversize="onOversize" />
    </div>
    <van-divider
      :style="{ color: '#1989fa', borderColor: '#1989fa', padding: '0 16px' }"
    >
      个人信息
    </van-divider>
    <!-- 个人信息修改 -->
    <div class="info">
      <van-field v-model="nickname" label="昵称" clearable />
      <van-field v-model="phone" type="tel" label="手机号" clearable />
      <van-field v-model="description" label="个人描述" rows="2" autosize type="textarea" maxlength="100" show-word-limit clearable />
    </div>
    <div class="action">
      <div class="btn-wrapper">
        <van-button
          @click="saveAll"
          class="upload-btn" 
          type="info"
        >
          保存
        </van-button>
        <van-button
          @click="resetAll"
          class="upload-btn" 
          type="default"
        >
          重置
        </van-button>
      </div>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex'
import TopPart from 'components/Home/TopPart'
import "cropperjs/dist/cropper.css"
import Cropper from "cropperjs"
import { getUserInfo } from '@/api/user'
import { editUserB } from '@/api/admin'
import { baseUrl } from '@/utils/setting'

export default {
  computed: mapState([ 'userInfo' ]),
  data() {
    return {
      id: undefined,
      userAvatar: undefined,
      nickname: undefined,
      phone: undefined,
      description: undefined,
      background: [],

      showCrop: false,
      myCropper: "",
      flagX: false //裁剪的图片是否反转，默认false(不反转)
    }
  },
  mounted() {
    this.initUserInfo()
    this.initCropper()
  },
  methods: {
    ...mapMutations(['updateInfo']),
    // 更新缓存
    updateCache() {
      let data = {
        avatar: this.userAvatar,
        background: this.background[0].url,
        nickname: this.nickname,
        phone: this.phone,
        description: this.description
      }
      this.updateInfo(data)
    },
    // 接口 - 个人信息
    initUserInfo() {
      getUserInfo({ username: this.userInfo.username }).then(res => {
        if(res.data.code === '0') {
          this.$toast.success(res.data.desc)
          let detail = res.data.userInfo
          this.id = detail.id
          this.userAvatar = detail.avatar
          this.nickname = detail.nickname
          this.phone = detail.phone
          this.description = detail.description
          this.background = []
          this.background.push({ url: detail.background })
          this.updateCache()
        } else {
          this.$toast.fail(res.data.desc)
        }
      }).catch(err => {
        this.$toast.fail(res.data.desc)
      })
    },
    // 处理背景图超过限制大小
    onOversize(file) {
      this.$toast.fail("上传图片过大，最大为5MB")
    },

    initCropper() {
      // 创建实例，与展示裁剪的img标签绑定
      let cropImageDom = document.querySelector("#cropImage");
      this.myCropper = new Cropper(cropImageDom, {
        aspectRatio: 1 / 1,
        // viewMode: 0,
        // minContainerWidth: 100,
        // minContainerHeight: 100,
        // preview: ".previewBox",
        guides: false, // 裁剪框的虚线(九宫格)
        autoCropArea: 0.5, // 0-1之间的数值，定义自动剪裁区域的大小，默认0.8
        movable: true, // 是否允许移动图片
        dragCrop: true, // 是否允许移除当前的剪裁框，并通过拖动来新建一个剪裁框区域
        movable: true, // 是否允许移动剪裁框
        resizable: true, // 是否允许改变裁剪框的大小
        zoomable: true, // 是否允许缩放图片大小
        mouseWheelZoom: false, // 是否允许通过鼠标滚轮来缩放图片
        touchDragZoom: true, // 是否允许通过触摸移动来缩放图片
        rotatable: true, // 是否允许旋转图片
        crop: function(e) {
          // 输出结果数据裁剪图像。
        }
      })
    },
    // 点击头像
    clickPhoto() {
      this.$refs["imageRead"].click();
    },
    // 选择图片
    selectImage(e) {
      let targetFile = e.target.files[0];
      // console.log(targetFile)
      if (targetFile) {
        this.showCrop = true;
        this.flagX = false;
        let reader = new FileReader();
        /* readAsDataURL 方法会读取指定的 Blob 或 File 对象。
        读取操作完成的时候，readyState 会变成已完成DONE，
        并触发 loadend 事件，同时 result 属性将包含一个data:URL格式的字符串（base64编码）
        以表示所读取文件的内容。*/
        reader.readAsDataURL(targetFile);
        reader.onload = () => {
          let dataURL = reader.result;
          let cropImageDom = document.querySelector("#cropImage");
          cropImageDom.src = dataURL;
          this.myCropper.replace(dataURL);
        };
        // 避免下次选择同一图片不触发
        e.target.value = "";
      }
    },
    // 取消裁剪
    cancelCrop() {
      this.showCrop = false;
    },
    largerImg() {
      this.myCropper.zoom(0.1)
    },
    smallerImg() {
      this.myCropper.zoom(-0.1)
    },
    // 复位
    resetCrop() {
      this.flagX = false;
      this.myCropper.reset();
    },
    // 反转
    scaleCrop() {
      if (this.flagX) {
        this.myCropper.scaleX(1), (this.flagX = false);
      } else {
        this.myCropper.scaleX(-1), (this.flagX = true);
      }
    },
    // 旋转
    rotateCrop() {
      this.myCropper.rotate(45);
    },
    // DONE：确定裁剪并上传
    // 上传base64图片
    submitCrop() {
      let cas = this.myCropper.getCroppedCanvas();
      let base64 = cas.toDataURL("image/png");
      let data = {
        name: this.userInfo.username,
        img: base64
      }
      this.$axios.post(baseUrl+'/user/uploadAvatar', data).then(res => {
        if(res.data.code === '0') {
              console.log(res.data)
              let file = baseUrl + '/avatars/' + res.data.filename
              this.userAvatar = file
              this.$toast('上传成功')
          } else {
              //上传后，失败
              this.$toast('上传失败')
          }
      }).catch(err => {
          //上传后，失败
          this.$toast('上传失败')
      })

      this.showCrop = false;
    },

    // 背景图上传前验证
    beforeRead(file) {
      if (file.type !== 'image/jpeg' && file.type !== 'image/jpg' && file.type !== 'image/png') {
        this.$toast.fail('请上传 jpg 或 png 格式图片');
        return false;
      }
      return true;
    },
    // DONE: 背景图上传
    // 先上传图片再保存用户信息
    afterRead(file) {
      //正在上传
      file.status = 'uploading'
      file.message = '上传中...'
      let formData = new FormData()
      formData.append('file', file.file)
      //上传接口
      this.$axios.post(baseUrl+'/user/uploadBackground', formData, {
          headers: {
              'content-type': 'multipart/form-data',
          }
      }).then(res => {
          if(res.data.code === '0') {
              console.log(res.data)
              this.background = []
              let file = baseUrl + '/backgrounds/' + res.data.filename
              this.background.push({ url: file })
              file.status = 'done'
              file.message = '上传成功'
          } else {
              //上传后，失败
              file.status = 'failed'
              file.message = '上传失败'
          }
      }).catch(err => {
          //上传后，失败
          file.status = 'failed'
          file.message = '上传失败'
      })
    },

    // 保存所有表单信息
    saveAll() {
      // console.log(this.background)
      this.$dialog.confirm({
        title: '保存',
        message: '确认保存所有信息？',
      })
        .then(() => {
          // on confirm
          // 默认头像(本地)
          const defaultAvatar = '/static/img/avatar.jpg'
          // 默认背景图（本地）
          const defaultBg = '/static/img/bg1.png'
          let data = {
            id: this.id,
            userForm: {
              avatar: this.userAvatar || defaultAvatar,
              nickname: this.nickname || null,
              phone: this.phone || null,
              description: this.description || '此人很懒，什么也没写~',
              background: this.background[0].url ? this.background[0].url : defaultBg,
            }
          }
          editUserB(data).then(res => {
            if(res.data.code === '0') {
              this.$message.success(res.data.desc)
              this.initUserInfo()
            } else {
              this.$message.error(res.data.desc)
            }
          }).catch(err => {
            this.$message.error(res.data.desc)
          })
        })
        .catch(() => {
          // on cancel
          this.$toast('注意：离开此页所有新信息将丢失')
        });
      
    },
    // 重置
    resetAll() {
      Dialog.confirm({
        title: '重置',
        message: '所有新信息将丢失，是否重置表单信息？',
      })
        .then(() => {
          // on confirm
          this.initUserInfo()
        })
        .catch(() => {
          // on cancel
        });
    }
  },
  components: {
    TopPart
  }
}
</script>

<style lang="scss" scoped>
::v-deep .van-field__control {
  color: #999;
}
.avatar-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  .avatar-img {
    max-width: 100%;
    width: 100px;
    height: 100px;
    border-radius: 50%;
  }
}
.bg {
  text-align: center;
}
.action {
  margin-bottom: 65px;
  text-align: center;
  .btn-wrapper {
    text-align: center;
    .upload-btn {
      padding: 0 30px;
      margin: 0 5px;
    }
  }
}
.crop-wrapper {
  height: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  & > div {
    width: 100%;
  }
  & > div:first-child {
    height: 70%;
    background: rgb(12, 12, 12);
  }
  & > div:last-child {
    text-align: center;
  }
}
.imageRead {
  display: none;
}
.photo-wrap {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  .photo {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    object-fit: contain;
    box-shadow: 0 1px 4px rgba(0,21,41,.08);
  }
}
</style>